﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Vds2465Telegrams;

namespace Vds2465Parser
{
    internal static class GenParse_UserData_55_SupportedUserDataTypes
    {
        #region private constants

        private const int NrOfHeaderBytes = 3;

        #endregion private constants

        #region internal methods

        internal static byte[] GenerateBytes(UserData userData)
        {
            byte[] userDataBytes = null;

            if (userData is UserData_55_SupportedUserDataTypes)
            {
                UserData_55_SupportedUserDataTypes userData55 = userData as UserData_55_SupportedUserDataTypes;
                int nrOfSupTypes = 0;
                if (userData55.SupportedUserDataTypes != null)
                {
                    nrOfSupTypes = userData55.SupportedUserDataTypes.Count;
                    if (nrOfSupTypes > 250)
                    {
                        // TODO handle error and check if 250 the correct constant to compare against?
                    }
                }
                byte nrOfBytes = (byte) (NrOfHeaderBytes + nrOfSupTypes);

                userDataBytes = new byte[nrOfBytes];
                userDataBytes[0] = (byte) (nrOfBytes - GenParse_UserData.HeaderLength);	// user data length
                userDataBytes[1] = UserData.UserData55SupportedUserDataTypes;
                userDataBytes[2] = userData55.Device;
                if (userData55.SupportedUserDataTypes != null)
                {
					for (int index = 0; index < userData55.SupportedUserDataTypes.Count; index++)
                    {
						userDataBytes[NrOfHeaderBytes + index] = userData55.SupportedUserDataTypes.ElementAt(index);
                    }
                }
            }
            else
            {
                // TODO handle error
            }

            return userDataBytes;
        }

        internal static bool ParseBytes(byte[] userDataBytes, out UserData userData55SupportedUserDataTypes, out int consumedBytes)
        {
            userData55SupportedUserDataTypes = null;
            consumedBytes = 0;

            if (userDataBytes.Length >= NrOfHeaderBytes)
            {
				byte setLength = userDataBytes[0];
				if (userDataBytes.Length >= setLength + 2)
				{
					if (userDataBytes[0] > 0)
					{
						// first byte                
						if (userDataBytes[1] == UserData.UserData55SupportedUserDataTypes)
						{
							byte device = userDataBytes[2];
							byte nrOfSupTypes = (byte) (userDataBytes[0] - 1);
							SortedSet<byte> supTypes = new SortedSet<byte>();
							// byte[] supTypes = new byte[nrOfSupTypes];
							for (int index = 0; index < nrOfSupTypes; index++)
							{
								supTypes.Add(userDataBytes[3 + index]);
							}

							userData55SupportedUserDataTypes = new UserData_55_SupportedUserDataTypes(device, supTypes);
							consumedBytes = NrOfHeaderBytes + nrOfSupTypes;

							return true;
						}

						// wrong value for the data type
						return false;

					}

					// TODO handle error (wrong value in first byte the length)
					return false;
				}
			
				// TODO handle error: not enough bytes as specified by the SL value
				return false;
			}

            // TODO handle error (not enough bytes)
            return false;
        }

        #endregion internal methods
    }
}
